package com.health_predict_springboot.service.impl;

import com.health_predict_springboot.dao.HealthIndicatorMapper;
import com.health_predict_springboot.dao.HealthRiskMapper;
import com.health_predict_springboot.pojo.HealthIndicator;
import com.health_predict_springboot.pojo.HealthRisk;
import com.health_predict_springboot.service.HealthRiskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class HealthRiskServiceImpl implements HealthRiskService {

    @Autowired
    private HealthRiskMapper healthRiskMapper;
    
    @Autowired
    private HealthIndicatorMapper healthIndicatorMapper;

    @Override
    public HealthRisk getRiskById(Long riskId) {
        return healthRiskMapper.selectByRiskId(riskId);
    }

    @Override
    public HealthRisk getRiskByIndicatorId(Long indicatorId) {
        return healthRiskMapper.selectByIndicatorId(indicatorId);
    }

    @Override
    public List<HealthRisk> getRisksByUserId(Long userId) {
        return healthRiskMapper.selectByUserId(userId);
    }

    @Override
    public List<HealthRisk> getAllRisks() {
        return healthRiskMapper.selectAllRisks();
    }

    @Override
    public int addRisk(HealthRisk risk) {
        // 设置预测时间
        risk.setPredictTime(new Date());
        return healthRiskMapper.insertRisk(risk);
    }

    @Override
    public int updateRisk(HealthRisk risk) {
        return healthRiskMapper.updateRisk(risk);
    }

    @Override
    public int deleteRisk(Long riskId) {
        return healthRiskMapper.deleteRisk(riskId);
    }

    @Override
    public List<HealthRisk> getRisksByPage(Map<String, Object> params) {
        return healthRiskMapper.selectRisksByPage(params);
    }

    @Override
    public int getRiskCount(Map<String, Object> params) {
        return healthRiskMapper.selectRiskCount(params);
    }

    @Override
    public List<HealthRisk> getRisksByRiskLevel(String riskLevel) {
        return healthRiskMapper.selectByRiskLevel(riskLevel);
    }

    @Override
    public HealthRisk predictCardioRisk(Long indicatorId) {
        // 根据指标ID查询健康指标
        HealthIndicator indicator = healthIndicatorMapper.selectByIndicatorId(indicatorId);
        if (indicator == null) {
            return null;
        }
        
        // 计算心血管风险值（这里使用简化的模型）
        double riskValue = calculateRiskValue(indicator);
        
        // 确定风险等级
        String riskLevel = getRiskLevel(riskValue);
        
        // 确定风险贡献因子
        List<String> riskFactors = getRiskFactors(indicator);
        
        // 创建风险记录
        HealthRisk risk = new HealthRisk();
        risk.setIndicatorId(indicatorId);
        risk.setUserId(indicator.getUserId());
        risk.setCardioRisk(new BigDecimal(riskValue).setScale(4, RoundingMode.HALF_UP));
        risk.setRiskLevel(riskLevel);
        risk.setRiskFactors(String.join(",", riskFactors));
        
        // 生成改善建议
        String suggest = generateImprovementSuggest(risk);
        risk.setImprovementSuggest(suggest);
        
        // 保存到数据库
        addRisk(risk);
        
        return risk;
    }

    @Override
    public String generateImprovementSuggest(HealthRisk risk) {
        StringBuilder suggest = new StringBuilder();
        
        String riskLevel = risk.getRiskLevel();
        String[] factors = risk.getRiskFactors().split(",");
        
        switch (riskLevel) {
            case "高":
                suggest.append("建议立即就医，严格控制饮食，增加运动，戒烟限酒。\n");
                break;
            case "中":
                suggest.append("建议戒烟限酒，控制体重，增加运动，低盐饮食。\n");
                break;
            case "低":
                suggest.append("保持健康生活方式，定期体检。\n");
                break;
        }
        
        // 根据具体风险因子提供个性化建议
        for (String factor : factors) {
            switch (factor) {
                case "血压偏高":
                    suggest.append("- 血压偏高：减少盐分摄入，保持心情平静，定期监测血压。\n");
                    break;
                case "高血压":
                    suggest.append("- 高血压：严格按照医生建议服药，定期监测血压，避免剧烈运动。\n");
                    break;
                case "超重":
                    suggest.append("- 超重：控制饮食，增加有氧运动，每周至少进行150分钟中等强度运动。\n");
                    break;
                case "高胆固醇":
                    suggest.append("- 高胆固醇：减少高脂肪、高胆固醇食物摄入，增加膳食纤维摄入。\n");
                    break;
                case "高血糖":
                    suggest.append("- 高血糖：控制碳水化合物摄入，定期监测血糖，遵循医生建议。\n");
                    break;
                case "吸烟":
                    suggest.append("- 吸烟：立即戒烟，避免二手烟。\n");
                    break;
                case "饮酒":
                    suggest.append("- 饮酒：限制饮酒量，建议男性每日不超过25克酒精，女性不超过15克。\n");
                    break;
            }
        }
        
        suggest.append("建议定期进行健康体检，及时了解身体状况变化。");
        
        return suggest.toString();
    }
    
    // 计算风险值（简化模型）
    private double calculateRiskValue(HealthIndicator indicator) {
        double baseRisk = 0.05; // 基础风险值
        
        // 年龄因素
        if (indicator.getAge() >= 50) {
            baseRisk += 0.08;
        } else if (indicator.getAge() >= 40) {
            baseRisk += 0.05;
        } else if (indicator.getAge() >= 30) {
            baseRisk += 0.02;
        }
        
        // 性别因素（男性风险稍高）
        if (indicator.getGender() == 1) {
            baseRisk += 0.03;
        }
        
        // 血压因素
        if (indicator.getApHi() >= 140 || indicator.getApLo() >= 90) {
            baseRisk += 0.10;
        } else if (indicator.getApHi() >= 130 || indicator.getApLo() >= 85) {
            baseRisk += 0.05;
        }
        
        // 胆固醇因素
        if (indicator.getCholesterol() == 3) {
            baseRisk += 0.12;
        } else if (indicator.getCholesterol() == 2) {
            baseRisk += 0.06;
        }
        
        // 血糖因素
        if (indicator.getGluc() == 3) {
            baseRisk += 0.10;
        } else if (indicator.getGluc() == 2) {
            baseRisk += 0.05;
        }
        
        // BMI因素
        double bmi = indicator.getBmi().doubleValue();
        if (bmi >= 30) {
            baseRisk += 0.08;
        } else if (bmi >= 28) {
            baseRisk += 0.06;
        } else if (bmi >= 24) {
            baseRisk += 0.03;
        }
        
        // 吸烟因素
        if (indicator.getSmoke() == 1) {
            baseRisk += 0.07;
        }
        
        // 饮酒因素
        if (indicator.getAlco() == 1) {
            baseRisk += 0.04;
        }
        
        // 缺乏运动因素
        if (indicator.getActive() == 0) {
            baseRisk += 0.05;
        }
        
        // 确保风险值在0-1之间
        return Math.min(1.0, Math.max(0.0, baseRisk));
    }
    
    // 根据风险值确定风险等级
    private String getRiskLevel(double riskValue) {
        if (riskValue >= 0.20) {
            return "高";
        } else if (riskValue >= 0.10) {
            return "中";
        } else {
            return "低";
        }
    }
    
    // 获取风险贡献因子
    private List<String> getRiskFactors(HealthIndicator indicator) {
        List<String> factors = new ArrayList<>();
        
        // 血压
        if (indicator.getApHi() >= 140 || indicator.getApLo() >= 90) {
            factors.add("高血压");
        } else if (indicator.getApHi() >= 130 || indicator.getApLo() >= 85) {
            factors.add("血压偏高");
        }
        
        // 胆固醇
        if (indicator.getCholesterol() == 3) {
            factors.add("高胆固醇");
        } else if (indicator.getCholesterol() == 2) {
            factors.add("胆固醇偏高");
        }
        
        // 血糖
        if (indicator.getGluc() == 3) {
            factors.add("高血糖");
        } else if (indicator.getGluc() == 2) {
            factors.add("血糖偏高");
        }
        
        // BMI
        double bmi = indicator.getBmi().doubleValue();
        if (bmi >= 24) {
            factors.add("超重");
        }
        
        // 吸烟
        if (indicator.getSmoke() == 1) {
            factors.add("吸烟");
        }
        
        // 饮酒
        if (indicator.getAlco() == 1) {
            factors.add("饮酒");
        }
        
        // 缺乏运动
        if (indicator.getActive() == 0) {
            factors.add("缺乏运动");
        }
        
        // 如果没有明显风险因素
        if (factors.isEmpty()) {
            factors.add("无明显风险因素");
        }
        
        return factors;
    }
}